#include "IPrimitive.h"

void IPrimitive::applyViewMatrix(const CMatrix& view)
{
	//set the world view matrix
	m_worldViewMatrix = m_worldMatrix * view;

	//calculate the inverse
	m_inverseWorldViewMatrix = m_worldViewMatrix.inverse();
}

void IPrimitive::setMatrices(const CMatrix& T, const CMatrix& R, const CMatrix& S)
{
	//set world and rotation
	m_worldMatrix = S * R * T;
	
	//set inverses
	m_inverseWorldMatrix = m_worldMatrix.inverse();
}

/* set the world matrix of the primitive */
void IPrimitive::setWorldMatrix(const CMatrix& world)
{
	m_worldMatrix = world;
	m_inverseWorldMatrix = m_worldMatrix.inverse();
}

void IPrimitive::convertRayToLocalCoordinates(const CRay& in, CRay& out)const
{
	CVector3f dirS = CVector3f(0, 0, 0) * m_inverseWorldViewMatrix;
	CVector3f dirE = in.getDirection() * m_inverseWorldViewMatrix;

	CVector3f newDir = dirE - dirS;
	newDir.normalize();
	out.setDirection(newDir);

	//out.setDirection(in.getDirection() * m_inverseRotationViewMatrix);
	out.setOrigin(in.getOrigin() * m_inverseWorldViewMatrix);
	out.getDirection().normalize();
}

//convert a ray from global coorindates to local coordinates
void IPrimitive::globalToLocal(const CRay& in, CRay& out)const
{
	CVector3f dirS = CVector3f(0, 0, 0) * m_inverseWorldMatrix;
	CVector3f dirE = in.getDirection() * m_inverseWorldMatrix;

	CVector3f newDir = dirE - dirS;
	newDir.normalize();

	out.setDirection(newDir);
	out.setOrigin(in.getOrigin() * m_inverseWorldMatrix);

}

void IPrimitive::convertNormalToGlobalCoordinates(const CVector3f& in, CVector3f& out)const
{
	//out = in * m_rotationViewMatrix;
	CVector3f dirS = CVector3f(0, 0, 0) * m_worldViewMatrix;
	CVector3f dirE = in * m_worldViewMatrix;
	out = dirE - dirS;
	out.normalize();
}

void IPrimitive::convertPointToLocalCoordinates(const CVector3f& in, CVector3f& out)const
{
	out = in * m_inverseWorldViewMatrix;
}